<?php
/**
 * @copyright   Copyright(c) 2018
 * @author      tianjie
 * @link        http://www.tinphp.com/
 */

namespace tian;

class App
{
    /**
     * @var bool 应用调试模式
     */
    public static $debug = true;

    private static $config = [];
    private static $route = [];

    //执行应用程序
    public static function run(Request $request = null)
    {
        $request = is_null($request) ? Request::instance() : $request;

        //初始化配置信息
        $config = self::init();

        //初始化助手函数
        include(APP_SYS_PATH . "helper" . SUFFIX);

        //解析路由
        $route = self::route($request, $config);

        //记录当前调度信息
        $request->dispatch($route);

        //路由分发 执行
        self::implement($request, $route);
    }

    public static function implement($request, $route)
    {
        $moduleAry = $route['module'];
        if (is_string($moduleAry)) {
            $moduleAry = explode('/', $moduleAry);
        }

        if(IS_WIN){
            $module = strip_tags(strtolower($moduleAry[0] ?: self::$config['default_module']));
            $controller = strip_tags(strtolower($moduleAry[1] ?: self::$config['default_controller']));
            $action = strip_tags(strtolower($moduleAry[2] ?: self::$config['default_action']));
        }else{
            $module = strip_tags($moduleAry[0] ?: self::$config['default_module']);
            $controller = strip_tags($moduleAry[1] ?: self::$config['default_controller']);
            $action = strip_tags($moduleAry[2] ?: self::$config['default_action']);
        }

        //设置当前的模块名
        $request->module($module);
        //设置当前的模块名
        $request->controller($controller);
        //设置当前的模块名
        $request->action($action);

        
        $mvcController = APP_PATH . $module . "/controller";
        $mvcFileName = strtolower($controller) . '.php';
        
        //验证控制器文件是否存在
        $isExistence = false;
        $mvcClass = '';
        $mvcFile = '';
        $controllerAryList = get_filenamesbydir($mvcController);
        if(!empty($controllerAryList)){
            foreach ($controllerAryList as $item){
                if(strtolower($item['name']) == $mvcFileName){
                    $isExistence = true;
                    $mvcClass = $item['path'];
                    $mvcFile = $item['name'];
                }
            }
        }
        
        //检测控制器文件是否存在
        if ($isExistence) {
            //当前应用控制器文件路径
            $controllerPrimary = explode('.',$mvcFile)[0];
            $mvcControllerFile = sprintf("%s" . $module . "/controller" . "/%s", APP_PATH, $controllerPrimary);
            $mvcControllerClass = "\\app\\" . $module . "\\controller\\" . $controllerPrimary;
            //echo"<pre>";var_dump($mvcControllerClass);die;
            
            //实例化数据库操作类
            new Db();
            
            //实例化当前应用控制器
            $myfC = new $mvcControllerClass();

            if (is_object($myfC) && method_exists($myfC, $action)){
                //初始化系统方法 模板引擎
                $myfC->_sys_init_action($module, $controller);
                //执行前置方法
                $myfC->_before_action();
                //执行用户方法
                $myfC->{$action}();
                //执行后置方法
                $myfC->_after_action();
            }else{
                header('Content-Type:application/json; charset=utf-8');
                echo "The method ". $action ." () not found in class " . ucfirst($controller);
            }
        } else {
            header('Content-Type:application/json; charset=utf-8');
            echo "404 The page not found：" . $mvcController . '/' . $mvcFileName;
        }
    }

	//初始化载入配置
    public static function init()
    {
        //载入应用基础配置
        Config::load(CONFIG_PATH . 'config' . SUFFIX);

        //载入应用数据库配置
        $database = CONFIG_PATH . 'database' . SUFFIX;
        Config::load($database, 'database');

        //载入redis配置
        $redis = CONFIG_PATH . 'redis' . SUFFIX;
        Config::load($redis, 'redis');

        //载入view配置
		$view = CONFIG_PATH . 'view' . SUFFIX;
        Config::load($view, 'template');
		
		//载入日志配置
		$log = CONFIG_PATH . 'log' . SUFFIX;
        Config::load($log, 'log');
		
		//载入session配置
		$session = CONFIG_PATH . 'session' . SUFFIX;
        Config::load($session, 'session');
		
		//载入cookie配置
		$cookie = CONFIG_PATH . 'cookie' . SUFFIX;
        Config::load($cookie, 'cookie');

        //应用调试模式
        self::$debug = Config::get('app_debug');

        //载入公共函数文件
        $functionFile = CONFIG_PATH . "function" . SUFFIX;
        if (is_file($functionFile)) {
            include($functionFile);
        }

        return self::$config = Config::get();
    }

    public static function route($request, array $config)
    {
        $path = $request->path();
        $depr = config('pathinfo_depr');
        $result = false;

        //载入应用路由
        $files = CONFIG_PATH . 'route' . SUFFIX;
        if (file_exists($files)) {
            include $files;
        }

        //路由检测
        $result = Route::check($request, $path, $depr);

        //路由无效 自动解析模块的URL地址 [模块/控制器/操作?]参数1=值1&参数2=值2...
        if (false === $result) {
            $result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
        }

        return $result;
    }

    public static function getRoute($name)
    {
        return self::$route[$name] ?? null;
    }

    public static function getConfig($name)
    {
        if (!strpos($name, '.')) {
            return self::$config[$name] ?? null;
        }

        // 二维数组设置和获取支持
        $name = explode('.', $name);
        $obj = array();
        foreach ($name as $item) {
            if (empty($obj)) {
                $obj = self::$config[$item];
            } else {
                if (is_array($obj[$item])) {
                    $obj = $obj[$item];
                }
            }
        }
        $value = $obj[$name[count($name) - 1]];

        return $value ?? null;
    }

}